package cn.bbstone.pisces2.client.task.impl;

import cn.bbstone.pisces2.client.base.ClientCache;
import cn.bbstone.pisces2.client.task.TaskListener;
import cn.bbstone.pisces2.client.task.event.FailEvent;
import cn.bbstone.pisces2.client.task.event.FailEventData;
import cn.bbstone.pisces2.comm.Const;
import cn.bbstone.pisces2.comm.cache.ClientFliIndexCache;
import cn.bbstone.pisces2.comm.fli.FliSavePoint;
import cn.bbstone.pisces2.listener.OpEnum;
import cn.bbstone.pisces2.listener.OpUtil;
import cn.bbstone.pisces2.util.BFileUtil;
import cn.bbstone.pisces2.util.FLIUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.file.Files;
import java.nio.file.Paths;

public class ListTaskListener implements TaskListener {
    private static Logger log = LoggerFactory.getLogger(ListTaskListener.class);

    /**
     * after all LIST Data received, will execute this method to clean client cache
     * and update save-point
     *
     *
     * @param fliSavePoint
     */
    @Override
    public void onCompleted(FliSavePoint fliSavePoint) {
        // check latest fli.idx file checksum,if same as old fli.sp checksum,
        // will start req fileNo from old fli.sp fileNo filed
        String idxChecksum = BFileUtil.checksum(FLIUtil.getClientIndexPath());
        //
        FliSavePoint oldSp = null;
        if (Files.exists(Paths.get(FLIUtil.getClientSpPathStr()))) {
            oldSp = FLIUtil.readClientSavePoint();
        }
        if (oldSp != null && oldSp.getChecksum().equals(idxChecksum)) {
            // cache save-point file info
            ClientCache.setFliSavePoint(oldSp);
            log.info("-=1=-sp save to client cache, spCount: {}", ClientCache.getSpCount());
            //
            log.debug("--->->-->new received fli.idx no change, fli.sp will not update, and will start req file from flieNo= sp.fileNo");
        } else {
        // old savepoint file not exist or checksum not eq new fli.idx file checksum, new/update sp file
//        if (oldSp == null || !oldSp.getChecksum().equals(idxChecksum)) {
            // create fli.sp save-point file
            FliSavePoint fliSavePointDisk = new FliSavePoint();
            fliSavePointDisk.setChecksum(idxChecksum);
            fliSavePointDisk.setCount(FLIUtil.getFileLineCount(FLIUtil.getClientIndexPath()));
            fliSavePointDisk.setFileNo(fliSavePoint.getFileNo()); // fileNo = 0, fli.idx
            fliSavePointDisk.setUpdateTime(fliSavePoint.getUpdateTime());
            FLIUtil.writeClientSavePoint(fliSavePointDisk);
            // cache save-point file info
            ClientCache.setFliSavePoint(fliSavePointDisk);
            log.info("-=2=-sp save to client cache, spCount: {}, spCount2: {}", ClientCache.getSpCount(), fliSavePointDisk.getCount());
        }

        ClientFliIndexCache.init(Const.CLIENT);
        // close opening file(fileOutputStream)
        FileTask fileTask = ClientCache.getTask(fliSavePoint.getFileNo());
//        fileTask.closeFos();
        long oneFileTransferCostTimeMs = fileTask.costTimeMs();
        log.debug("<><>====<><> transfer file(fielNo: {}) cost time: {} ms. clientCache.size: {}",
                fliSavePoint.getFileNo(), oneFileTransferCostTimeMs, ClientCache.size());
        // remove file task of fileNo, should be zero here(RSP_LIST_DATA complete
        ClientCache.removeTask(fliSavePoint.getFileNo());
        
        // notify UI to update(load sp, idx to display)
        OpUtil.execListener(OpEnum.client_biz_meta_created);
        
        
    }

    @Override
    public void onFail(FailEvent failEvent) {
        FailEventData failEventData = failEvent.getFailEventData();
        //remove file task of fileNo
        ClientCache.removeTask(failEventData.getFileNo());
        log.error("fileNo({}) received file data error, reason: {}",
                failEventData.getFileNo(), failEventData.getReason());
    }

	@Override
	public void onSkip(FliSavePoint fliSavePoint) {
		// List skip do nothing
	}
}
